package org.shj.plugin.tdpl.gen;

import lombok.Data;
import lombok.Getter;
import lombok.Setter;
import org.apache.maven.plugin.AbstractMojo;
import org.apache.maven.plugin.MojoExecutionException;
import org.apache.maven.plugins.annotations.Mojo;
import org.apache.maven.plugins.annotations.Parameter;
import org.shj.plugin.tdpl.gen.generator.Generator;
import org.shj.plugin.tdpl.gen.generator.excel.AbstractXlsxGenerator;
import org.shj.plugin.tdpl.gen.generator.excel.MultiFileGenerator;
import org.shj.plugin.tdpl.gen.generator.excel.SingleFileGenerator;
import org.shj.tdpl.common.constant.TdplConstants;
import org.shj.plugin.tdpl.gen.db.AbstractDbConnect;
import org.shj.plugin.tdpl.gen.db.MssqlDbConnect;
import org.shj.plugin.tdpl.gen.db.MysqlDbConnect;
import org.shj.plugin.tdpl.gen.db.OracleDbConnect;
import org.springframework.jdbc.core.JdbcTemplate;
import org.springframework.jdbc.datasource.DriverManagerDataSource;

import java.io.File;

/**
 *
 * @author ShenHuangJian
 * @date 2018年6月25日
 *
 */
@Getter
@Setter
@Mojo(name="generator")
public class TdplMojo extends AbstractMojo{

	/**
	 * 以下是数据库连接需要的4个属性, 需要有权限访问系统表
	 */
	
	/**
	 * 数据库驱动类
	 */
	@Parameter(property="driverClassName", required=true)
	private String driverClassName;
	
	/**
	 * 数据库的 url
	 */
	@Parameter(property="url", required=true)
	private String url;
	
	/**
	 * 连接数据库的用户
	 */
	@Parameter(property="username", required=true)
	private String username;
	
	/**
	 * 连接数据库的密码
	 */
	@Parameter(property="password", required=true)
	private String password;
	
	/**
	 * 数据库的schema
	 */
	@Parameter(property="schema")
	private String schema;
	
	/**
	 * 每个表生成一个 excel
	 */
	@Parameter(property="genMultiFile", defaultValue="true")
	private boolean genMultiFile;
		
	/**
	 * 需要生成schema 的表的前辍。多个用逗号分隔
	 */
	@Parameter(property="includeTablePrefix")
	private String includeTablePrefix;
	
	/**
	 * 需要排除的表。多个用逗号分隔
	 */
	@Parameter(property="excludeTables")
	private String excludeTables;
	
	/**
     * Location of the file.
     */
    @Parameter( defaultValue = "${project.basedir}/src/test/resources/schemas", property = "outputDir" )
    private String outputDir;

	/** (non-Javadoc)
	 * @see org.apache.maven.plugin.Mojo#execute()
	 */
	@Override
	public void execute() throws MojoExecutionException {
		getLog().info("excel file generated in folder " + outputDir);
		File outputFolder = new File(outputDir);

		if(outputFolder.exists()) {
			if(outputFolder.isFile()) {
				throw new MojoExecutionException("The outputDir should be a folder.");
			}
		}else{
			boolean success = outputFolder.mkdirs();
			if(!success) {
				throw new MojoExecutionException("Can't create folder: " + outputDir +".");
			}
		}
		
		DriverManagerDataSource dataSource = new DriverManagerDataSource(url, username, password);
		dataSource.setDriverClassName(driverClassName);
		
		JdbcTemplate jdbcTemplate = new JdbcTemplate(dataSource);
		
		AbstractDbConnect dbConnect = retrieveDbConnectFromDriver();

		dbConnect.setJdbcTemplate(jdbcTemplate);
		dbConnect.setExcludeTables(excludeTables);
		dbConnect.setIncludeTablePrefix(includeTablePrefix);
		dbConnect.setSchema(schema);
		
		try {
			AbstractXlsxGenerator generator = getGenerator();
			generator.init(outputFolder.getAbsolutePath(), dbConnect);
		
			generator.generateSchema();

		}catch(Throwable e) {
			getLog().error(e.getMessage(), e);
			throw new MojoExecutionException("Generate schema failed.", e);
		}
		
	}
	
	private AbstractXlsxGenerator getGenerator() {
		if(genMultiFile) {
			return new MultiFileGenerator();
		}else {
			return new SingleFileGenerator();
		}
	}
	
	private AbstractDbConnect retrieveDbConnectFromDriver() throws MojoExecutionException{
		String driver = driverClassName.toLowerCase();
		if(driver.contains(TdplConstants.DB_MYSQL)) {
			return new MysqlDbConnect();
		}else if(driver.contains(TdplConstants.DB_MSSQL)) {
			return new MssqlDbConnect();
		}else if(driver.contains(TdplConstants.DB_ORACLE)) {
			return new OracleDbConnect();
		}else {
            throw new MojoExecutionException("Not supported data source.");
		}
	}

}
